package com.bookbuf.api.clients.c;

import com.bookbuf.api.configurations.ConfigurationContext;
import com.bookbuf.api.configurations.IConfiguration;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * author: robert.
 * date :  16/8/3.
 */
public final class CustomerFactoryImpl {

    private static final Constructor<CustomerApi> _CONSTRUCTOR;
    private static final Constructor<CustomerApi> _CONSTRUCTOR_MOCK;
    private static IConfiguration conf;

    static {

        Constructor constructor;
        Class clazz;
        try {
            clazz = Class.forName("com.bookbuf.api.clients.c.CustomerApiImpl");
            constructor = clazz.getDeclaredConstructor(IConfiguration.class);
        } catch (NoSuchMethodException e) {
            throw new AssertionError(e);
        } catch (ClassNotFoundException e) {
            throw new AssertionError(e);
        }
        _CONSTRUCTOR = constructor;

    }

    static {

        Constructor constructor;
        Class clazz;
        try {
            clazz = Class.forName("com.bookbuf.api.clients.c.CustomerApiMockImpl");
            constructor = clazz.getDeclaredConstructor(IConfiguration.class, CustomerApi.class);
        } catch (NoSuchMethodException e) {
            throw new AssertionError(e);
        } catch (ClassNotFoundException e) {
            throw new AssertionError(e);
        }
        _CONSTRUCTOR_MOCK = constructor;

    }

    public CustomerFactoryImpl() {
        this(ConfigurationContext.getConfiguration());
    }

    public CustomerFactoryImpl(IConfiguration IConfiguration) {
        if (IConfiguration == null) {
            throw new NullPointerException("configuration cannot be null");
        }
        conf = IConfiguration;
    }

    public CustomerApi getInstance() {
        try {
            final CustomerApi resources = _CONSTRUCTOR.newInstance(conf);
            if (conf.isMockMode())
                return _CONSTRUCTOR_MOCK.newInstance(conf, resources);
            else
                return resources;
        } catch (InstantiationException e) {
            throw new AssertionError(e);
        } catch (IllegalAccessException e) {
            throw new AssertionError(e);
        } catch (InvocationTargetException e) {
            throw new AssertionError(e);
        }
    }
}
